Description
Show a team's complete season schedule (past results + upcoming fixtures) beyond the polled fetch window, via ESPN's team-schedule endpoint. Reachable from a team (e.g. from the detail view or a favorite). Generalizes TASK-009 (favorite last/next beyond window) โ the schedule endpoint backs both.
Acceptance Criteria
- #1 User can view a single team's full schedule (results + upcoming)
- #2 Data comes from the ESPN team-schedule endpoint, decoded in internal/espn into model types
- #3 Schedule entries show date, opponent, home/away, and result/score when played
- #4 Reachable from a team in the UI (detail view or favorites)
Implementation Plan
- model.TeamSchedule{Team,Season,Games []model.Game} (reuse Game).
- espn.Client.TeamSchedule(ctx,l,teamID): GET teams/{id}/schedule; events[] like scoreboard BUT score is object {value,displayValue} -> schedule-specific competitor decode; reuse mapState/parseTime. Refactor mapTeam to share teamFromJSON.
- UI viewSchedule: opened via g=away / G=home from a dashboard game card or detail view, and via enter on a standings row. Past results (score + W/L tint) + upcoming, scroll-clamped. esc returns to prior view.
- Closes/supersedes TASK-009 (favorite last/next) via same endpoint.
Final Summary
Added a full team-schedule view (viewSchedule).
What:
- model.TeamSchedule{Team,Season,Games []model.Game} (reuses Game).
- espn.Client.TeamSchedule fetches teams/{id}/schedule and maps events into model.Game. The schedule endpoint sends competitor score as an object {value,displayValue} (vs the scoreboard's bare string), so schedCompetitor/scoreObj decode separately; mapScheduleGame reuses mapState/parseTime and a new shared teamFromJSON helper (mapTeam refactored onto it). Games sorted chronologically.
- UI: schedule.go renders past results (W/L/T + score, win-tinted) and upcoming fixtures (start time) with an 'upcoming' divider; opens scrolled to the next game. Reached three ways via openSchedule(): g/G (away/home, mirroring f/F favoriting) from a dashboard game card or the detail view, and enter on a standings row. prevMode records the opener so esc returns there; r refreshes.
Supersedes TASK-009 (favorite last/next beyond the fetch window) โ same endpoint.
Tests: mapScheduleGame (object score, home/away, winner, state) and the no-competition (bye) skip. Live-smoke verified a 163-game MLB schedule maps with scores. go vet + go test ./... pass.